hex_digit        [0-9A-F]
digit            [0-9]
alpha            [a-zA-Z_]
white_space      [ \r\t\n]*
num              ("-")?{digit}+
uint             {digit}+
int              {digit}+
float            ({num})("."{num}?)
hex_int          {hex_digit}+"h"
identifier       {alpha}+({digit}|{alpha})*

%%
"/*"			{ Comment(); }
"//"[^\n]*      { Count(); }


"bool"			{ Count(); return BOOL_TKN; }
"break"			{ Count(); return BREAK; }
"case"			{ Count(); return CASE; }
"const"			{ Count(); return CONST; }
"continue"		{ Count(); return CONTINUE; }
"default"		{ Count(); return DEFAULT; }
"do"			{ Count(); return DO; }
"else"			{ Count(); return ELSE; }
"enum"			{ Count(); return ENUM; }
"for"			{ Count(); return FOR; }
"goto"			{ Count(); return GOTO; }
"if"			{ Count(); return IF; }
"inline"		{ Count(); return INLINE; }
"Int"			{ Count(); return INT; }
"Int8"			{ Count(); return INT8; }
"Int16"			{ Count(); return INT16; }
"Int32"			{ Count(); return INT32; }
"UInt"			{ Count(); return UINT; }
"UInt8"			{ Count(); return UINT8; }
"UInt16"		{ Count(); return UINT16; }
"UInt32"		{ Count(); return UINT32; }
"Float"			{ Count(); return FLOAT; }
"Float32"		{ Count(); return FLOAT32; }
"Float64"		{ Count(); return FLOAT64; }
"return"		{ Count(); return RETURN; }
"sizeof"		{ Count(); return SIZEOF; }
"static"		{ Count(); return STATIC; }
"class"			{ Count(); return CLASS; }
"switch"		{ Count(); return SWITCH; }
"typedef"		{ Count(); return TYPEDEF; }
"union"			{ Count(); return UNION; }
"void"			{ Count(); return VOID; }
"volatile"		{ Count(); return VOLATILE; }
"while"			{ Count(); return WHILE; }

{hex_int}       { Count(); sscanf(yytext, "%X", &yylval.s); return INT_CONST; }
{int}           { Count(); sscanf(yytext, "%d", &yylval.s); return INT_CONST; }
{float}         { Count(); sscanf(yytext, "%f", &yylval.f); return FLOAT_CONST; }
{identifier}    { Count(); memcpy(yylval.name, yytext, yyleng + 1); return IDENTIFIER; }


alpha?\"(\\.|[^\\"\n])*\" { Count(); return STRING_LITERAL; }

"..."           { Count(); return ELLIPSIS; }
">>="           { Count(); return RIGHT_ASSIGN; }
"<<="           { Count(); return LEFT_ASSIGN; }
"+="            { Count(); return ADD_ASSIGN; }
"-="            { Count(); return SUB_ASSIGN; }
"*="            { Count(); return MUL_ASSIGN; }
"/="            { Count(); return DIV_ASSIGN; }
"%="            { Count(); return MOD_ASSIGN; }
"&="            { Count(); return AND_ASSIGN; }
"^="            { Count(); return XOR_ASSIGN; }
"|="            { Count(); return OR_ASSIGN; }
">>"            { Count(); return RIGHT_OP; }
"<<"            { Count(); return LEFT_OP; }
"++"            { Count(); return INC_OP; }
"--"            { Count(); return DEC_OP; }
"->"            { Count(); return PTR_OP; }
"&&"            { Count(); return AND_OP; }
"||"            { Count(); return OR_OP; }
"<="            { Count(); return LE_OP; }
">="            { Count(); return GE_OP; }
"=="            { Count(); return EQ_OP; }
"!="            { Count(); return NE_OP; }
";"             { Count(); return ';'; }
"{"             { Count(); return '{'; }
"}"             { Count(); return '}'; }
","             { Count(); return ','; }
":"             { Count(); return ':'; }
"="             { Count(); return '='; }
"("             { Count(); return '('; }
")"             { Count(); return ')'; }
"["             { Count(); return '['; }
"]"             { Count(); return ']'; }
"."             { Count(); return '.'; }
"&"             { Count(); return '&'; }
"!"             { Count(); return '!'; }
"~"             { Count(); return '~'; }
"-"             { Count(); return '-'; }
"+"             { Count(); return '+'; }
"*"             { Count(); return '*'; }
"/"             { Count(); return '/'; }
"%"             { Count(); return '%'; }
"<"             { Count(); return '<'; }
">"             { Count(); return '>'; }
"^"             { Count(); return '^'; }
"|"             { Count(); return '|'; }
"?"             { Count(); return '?'; }
[ \t\v\n\r\f]   { Count(); }
.               { printf("(0x%X) ", *yytext); yyerror("Unknown character"); }

%%

int yywrap(void)
{
	return 1;
}


void Comment(void)
{
	char c, prev = 0;
  
	while ((c = input()) != 0) /* (EOF maps to 0) */
	{
		if (c == '/' && prev == '*')
			return;
		prev = c;
	}
	yyerror("unterminated comment");
}

void Count(void)
{
	int i;

	for (i = 0; yytext[i] != '\0'; i++)
	{
		if (yytext[i] == '\n')
			col = 0, ++row;
		else if (yytext[i] == '\t')
			col += 8 - (col % 8);
		else
			col++;
	}
}


int CheckType(void)
{
/*
* pseudo code --- this is what it should check
*
*	if (yytext == struct_or_union_or_class_or_function)
*		return TYPE_NAME;
*
*	return IDENTIFIER;
*/

	return IDENTIFIER;
}
